home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / macintosh-c / macc-carbon-demos-nonbinhex.sit / macc-carbon-demos-nonbinhex / chap20-demo-classic events / Scrap.c < prev    next >
C/C++ Source or Header  |  2001-05-30  |  29KB  |  1,059 lines

  1. // *******************************************************************************************
  2. // Scrap.c                                                                 CLASSIC EVENT MODEL
  3. // *******************************************************************************************
  4. // 
  5. // This program utilises Carbon Scrap Manager functions to allow the user to:
  6. //
  7. // •    Cut, copy, clear, and paste text and pictures from and to two document windows opened by
  8. //        the program.
  9. //
  10. // •    Paste text and pictures cut or copied from another application to the two document 
  11. //        windows.
  12. //
  13. // •    Open and close a Clipboard window, in which the current contents of the scrap are
  14. //        displayed.
  15. //
  16. // The program's preferred scrap flavour type is 'TEXT'.  Thus, if the scrap contains data in
  17. // both the 'TEXT' and 'PICT' flavour types, only the 'TEXT' flavour will be used for pastes
  18. // to the document windows and and for display in the Clipboard window.
  19. //
  20. // In order to keep that part of the source code that is not related to the Carbon Scrap 
  21. // Manager to a minimum, the windows do not display insertion points, nor can the pictures be
  22. // dragged within the windows.  The text and pictures are not inserted into a document as 
  23. // such.  When the Paste item in the Edit menu is chosen:
  24. //
  25. // •    The text or picture on the Clipboard is simply drawn in the centre of the active window.
  26. //
  27. // •    A handle to the text or picture is assigned to fields in a document structure associated
  28. //        with the window.  (The demonstration program at MonoTextEdit shows how to cut, copy, and
  29. //    paste text from and to a TextEdit structure using the scrap.) 
  30. //
  31. // For the same reason, highlighting the selected text or picture in a window is achieved by
  32. // simply inverting the image.
  33. //
  34. // The program utilises the following resources:
  35. //
  36. // •    A 'plst' resource.
  37. //
  38. // •    An 'MBAR' resource, and 'MENU' resources for Apple, File, and Edit menus (preload, 
  39. //        non-purgeable).  
  40. //
  41. // •    Three 'WIND' resources (purgeable) (initially visible), two for the program's main
  42. //        windows and one for the Clipboard window.  
  43. //
  44. // •    A 'TEXT' resource (non-purgeable) containing text displayed in the left window at 
  45. //        program    start. 
  46. //
  47. // •    A 'PICT' resource (non-purgeable) containing a picture displayed in the right window at
  48. //        program start.
  49. //
  50. // •    A 'STR#' resource (purgeable) containing strings to be displayed in the error Alert.
  51. //
  52. // •    A 'SIZE' resource with the acceptSuspendResumeEvents, canBackground, 
  53. //        doesActivateOnFGSwitch, and isHighLevelEventAware flags set.
  54. //
  55. // *******************************************************************************************
  56.  
  57. // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… includes
  58.  
  59. #include <Carbon.h>
  60.  
  61. // …………………………………………………………………………………………………………………………………………………………………………………………………………………………… defines
  62.  
  63. #define rMenubar                    128
  64. #define mAppleApplication    128
  65. #define  iAbout                        1
  66. #define mFile                            129
  67. #define  iClose                        4
  68. #define  iQuit                        12
  69. #define mEdit                            130
  70. #define  iCut                            3
  71. #define  iCopy                        4
  72. #define  iPaste                        5
  73. #define  iClear                        6
  74. #define  iClipboard                8
  75. #define rWindow                        128
  76. #define rClipboardWindow    130
  77. #define rText                            128
  78. #define rPicture                    128
  79. #define rErrorStrings            128
  80. #define  eFailMenu                1
  81. #define  eFailWindow            2
  82. #define  eFailDocStruc        3
  83. #define  eFailMemory            4
  84. #define  eClearScrap            5
  85. #define  ePutScrapFlavor    6
  86. #define  eGetScrapSize        7
  87. #define  eGetScrapData        8        
  88. #define kDocumentType            1
  89. #define kClipboardType        2
  90. #define MAX_UINT32                0xFFFFFFFF
  91.  
  92. // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… typedefs
  93.  
  94. typedef struct
  95. {
  96.     PicHandle    pictureHdl;
  97.     Handle        textHdl;
  98.     Boolean        selectFlag;
  99.     SInt16        windowType;
  100. } docStructure, **docStructureHandle;
  101.  
  102. // …………………………………………………………………………………………………………………………………………………………………………………………………… global variables
  103.  
  104. Boolean        gRunningOnX                    = false;
  105. Boolean        gDone;
  106. WindowRef    gWindowRefs[2];
  107. WindowRef    gClipboardWindowRef    = NULL;
  108. Boolean        gClipboardShowing        = false;
  109. SInt16        gPixelDepth;
  110. Boolean        gIsColourDevice            = false;
  111.  
  112. // …………………………………………………………………………………………………………………………………………………………………………………………… function prototypes
  113.  
  114. void    main                                    (void);
  115. void    doPreliminaries                (void);
  116. OSErr    quitAppEventHandler        (AppleEvent *,AppleEvent *,SInt32);
  117. void    doEvents                            (EventRecord *);
  118. void    doUpdate                            (EventRecord *);
  119. void    doOSEvent                            (EventRecord *);
  120. void    doAdjustMenus                    (void);
  121. void    doMenuChoice                    (SInt32);
  122. void    doErrorAlert                    (SInt16);
  123. void    doOpenWindows                    (void);
  124. void    doCloseWindow                    (void);
  125. void    doInContent                        (Point);
  126. void    doCutCopyCommand            (Boolean);
  127. void    doPasteCommand                (void);
  128. void    doClearCommand                (void);
  129. void    doClipboardCommand        (void);
  130. void    doDrawClipboardWindow    (void);
  131. void    doDrawDocumentWindow    (WindowRef);
  132. Rect    doSetDestRect                    (Rect *,WindowRef);
  133. void    doGetDepthAndDevice        (void);
  134.  
  135. // ************************************************************************************** main
  136.  
  137. void  main(void)
  138. {
  139.     MenuBarHandle    menubarHdl;
  140.     SInt32                response;
  141.     MenuRef                menuRef;
  142.     Boolean              gotEvent;
  143.     EventRecord      eventStructure;
  144.  
  145.     // ……………………………………………………………………………………………………………………………………………………………………………………………… do preliminaries
  146.  
  147.     doPreliminaries();
  148.  
  149.     // ……………………………………………………………………………………………………………………………………………………………………… set up menu bar and menus
  150.     
  151.     menubarHdl = GetNewMBar(rMenubar);
  152.     if(menubarHdl == NULL)
  153.         doErrorAlert(eFailMenu);
  154.     SetMenuBar(menubarHdl);
  155.     DrawMenuBar();
  156.  
  157.     Gestalt(gestaltMenuMgrAttr,&response);
  158.     if(response & gestaltMenuMgrAquaLayoutMask)
  159.     {
  160.         menuRef = GetMenuRef(mFile);
  161.         if(menuRef != NULL)
  162.         {
  163.             DeleteMenuItem(menuRef,iQuit);
  164.             DeleteMenuItem(menuRef,iQuit - 1);
  165.             DisableMenuItem(menuRef,0);
  166.         }
  167.  
  168.         gRunningOnX = true;
  169.     }
  170.  
  171.     // ………………………………………………………………………………………………………………………………………………………………………………………………………… open windows
  172.  
  173.     doOpenWindows();
  174.  
  175.     // ………………………………………… get pixel depth and whether colour device for function SetThemeTextColor
  176.     
  177.     doGetDepthAndDevice();
  178.  
  179.     // ………………………………………………………………………………………………………………………………………………………………………………………………… enter eventLoop
  180.     
  181.     gDone = false;
  182.  
  183.     while(!gDone)
  184.     {
  185.         gotEvent = WaitNextEvent(everyEvent,&eventStructure,MAX_UINT32,NULL);
  186.  
  187.         if(gotEvent)
  188.             doEvents(&eventStructure);
  189.     }
  190. }
  191.  
  192. // *************************************************************************** doPreliminaries
  193.  
  194. void  doPreliminaries(void)
  195. {
  196.     OSErr    osError;
  197.  
  198.     MoreMasterPointers(96);
  199.     InitCursor();
  200.     FlushEvents(everyEvent,0);
  201.  
  202.     osError = AEInstallEventHandler(kCoreEventClass,kAEQuitApplication,
  203.                                                         NewAEEventHandlerUPP((AEEventHandlerProcPtr) quitAppEventHandler),
  204.                                                         0L,false);
  205.     if(osError != noErr)
  206.         ExitToShell();
  207. }
  208.  
  209. // **************************************************************************** doQuitAppEvent
  210.  
  211. OSErr  quitAppEventHandler(AppleEvent *appEvent,AppleEvent *reply,SInt32 handlerRefcon)
  212. {
  213.     OSErr            osError;
  214.     DescType    returnedType;
  215.     Size            actualSize;
  216.  
  217.     osError = AEGetAttributePtr(appEvent,keyMissedKeywordAttr,typeWildCard,&returnedType,NULL,0,
  218.                                                             &actualSize);
  219.  
  220.     if(osError == errAEDescNotFound)
  221.     {
  222.         CallInScrapPromises();
  223.         gDone = true;
  224.         osError = noErr;
  225.     } 
  226.     else if(osError == noErr)
  227.         osError = errAEParamMissed;
  228.  
  229.     return osError;
  230. }
  231.  
  232. // ********************************************************************************** doEvents
  233.  
  234. void    doEvents(EventRecord *eventStrucPtr)
  235. {
  236.     WindowPartCode    partCode;
  237.     WindowRef                windowRef;
  238.  
  239.     switch(eventStrucPtr->what)
  240.     {
  241.         case kHighLevelEvent:
  242.             AEProcessAppleEvent(eventStrucPtr);
  243.             break;
  244.  
  245.         case mouseDown:
  246.             partCode = FindWindow(eventStrucPtr->where,&windowRef);
  247.  
  248.             switch(partCode)
  249.             {
  250.                 case inMenuBar:
  251.                     doAdjustMenus();
  252.                     doMenuChoice(MenuSelect(eventStrucPtr->where));
  253.                     break;
  254.  
  255.                 case inContent:
  256.                     if(windowRef != FrontWindow())
  257.                         SelectWindow(windowRef);
  258.                     else
  259.                         doInContent(eventStrucPtr->where);
  260.                     break;
  261.  
  262.                 case inDrag:
  263.                     DragWindow(windowRef,eventStrucPtr->where,NULL);
  264.                     break;
  265.  
  266.                 case inGoAway:
  267.                     if(TrackGoAway(windowRef,eventStrucPtr->where) == true)
  268.                         doCloseWindow();
  269.                     break;
  270.             }
  271.             break;
  272.  
  273.         case keyDown:
  274.             if((eventStrucPtr->modifiers & cmdKey) != 0)
  275.             {
  276.                 doAdjustMenus();
  277.                 doMenuChoice(MenuEvent(eventStrucPtr));
  278.             }
  279.             break;
  280.  
  281.         case updateEvt:
  282.             doUpdate(eventStrucPtr);
  283.             break;
  284.  
  285.         case activateEvt:
  286.             windowRef = (WindowRef) eventStrucPtr->message;
  287.             if(windowRef == gClipboardWindowRef)
  288.                 doDrawClipboardWindow();
  289.             break;
  290.  
  291.         case osEvt:
  292.             doOSEvent(eventStrucPtr);
  293.             break;
  294.     }
  295. }
  296.  
  297. // ********************************************************************************** doUpdate
  298.  
  299. void  doUpdate(EventRecord *eventStrucPtr)
  300. {
  301.     WindowRef                        windowRef;
  302.     docStructureHandle    docStrucHdl;
  303.     SInt32                            windowType;
  304.  
  305.     windowRef = (WindowRef) eventStrucPtr->message;
  306.     docStrucHdl = (docStructureHandle) GetWRefCon(windowRef);
  307.     windowType = (*docStrucHdl)->windowType;
  308.  
  309.     BeginUpdate(windowRef);
  310.  
  311.     if(windowType == kDocumentType)
  312.     {
  313.         if((*docStrucHdl)->pictureHdl != NULL || (*docStrucHdl)->textHdl != NULL)
  314.             doDrawDocumentWindow(windowRef);
  315.     }
  316.     else if(windowType == kClipboardType)
  317.         doDrawClipboardWindow();
  318.  
  319.     EndUpdate(windowRef);
  320. }
  321.  
  322. // ********************************************************************************* doOSEvent
  323.  
  324. void    doOSEvent(EventRecord *eventStrucPtr)
  325. {
  326.     switch((eventStrucPtr->message >> 24) & 0x000000FF)
  327.     {
  328.         case suspendResumeMessage:
  329.             if((eventStrucPtr->message & resumeFlag) == 1)
  330.             {
  331.                 SetThemeCursor(kThemeArrowCursor);
  332.                 if(gClipboardWindowRef && gClipboardShowing)
  333.                     ShowWindow(gClipboardWindowRef);
  334.             }
  335.             else
  336.             {
  337.                 if(gClipboardWindowRef && gClipboardShowing)
  338.                 ShowHide(gClipboardWindowRef,false);
  339.             }
  340.             break;
  341.     }
  342. }
  343.  
  344. // ***************************************************************************** doAdjustMenus
  345.  
  346. void  doAdjustMenus(void)
  347. {
  348.     MenuRef                            fileMenuRef, editMenuRef;
  349.     docStructureHandle    docStrucHdl;
  350.     ScrapRef                        scrapRef;
  351.     OSStatus                        osError;
  352.     ScrapFlavorFlags        scrapFlavorFlags;
  353.     Boolean                            scrapHasText = false, scrapHasPicture = false;
  354.  
  355.     fileMenuRef = GetMenuRef(mFile);
  356.     editMenuRef = GetMenuRef(mEdit);
  357.  
  358.     docStrucHdl = (docStructureHandle) GetWRefCon(FrontWindow());
  359.  
  360.     if((*docStrucHdl)->windowType == kClipboardType)
  361.         EnableMenuItem(fileMenuRef,iClose);
  362.     else
  363.         DisableMenuItem(fileMenuRef,iClose);
  364.  
  365.     if(((*docStrucHdl)->pictureHdl || (*docStrucHdl)->textHdl) && ((*docStrucHdl)->selectFlag))
  366.     {
  367.         EnableMenuItem(editMenuRef,iCut);
  368.         EnableMenuItem(editMenuRef,iCopy);
  369.         EnableMenuItem(editMenuRef,iClear);
  370.     }
  371.     else
  372.     {
  373.         DisableMenuItem(editMenuRef,iCut);
  374.         DisableMenuItem(editMenuRef,iCopy);
  375.         DisableMenuItem(editMenuRef,iClear);
  376.     }
  377.  
  378.     GetCurrentScrap(&scrapRef);
  379.  
  380.     osError = GetScrapFlavorFlags(scrapRef,kScrapFlavorTypeText,&scrapFlavorFlags);
  381.     if(osError == noErr)
  382.         scrapHasText = true;
  383.  
  384.     osError = GetScrapFlavorFlags(scrapRef,kScrapFlavorTypePicture,&scrapFlavorFlags);
  385.     if(osError == noErr)
  386.         scrapHasPicture = true;
  387.  
  388.     if((scrapHasText || scrapHasPicture) && ((*docStrucHdl)->windowType != kClipboardType))
  389.         EnableMenuItem(editMenuRef,iPaste);
  390.     else
  391.         DisableMenuItem(editMenuRef,iPaste);
  392.  
  393.     DrawMenuBar();
  394. }
  395.  
  396. // ****************************************************************************** doMenuChoice
  397.  
  398. void  doMenuChoice(SInt32 menuChoice)
  399. {
  400.     MenuID                menuID;
  401.     MenuItemIndex    menuItem;
  402.  
  403.     menuID = HiWord(menuChoice);
  404.     menuItem = LoWord(menuChoice);
  405.  
  406.     if(menuID == 0)
  407.         return;
  408.  
  409.     switch(menuID)
  410.     {
  411.         case mAppleApplication:
  412.             if(menuItem == iAbout)
  413.                 SysBeep(10);
  414.             break;
  415.  
  416.         case mFile:
  417.             if(menuItem == iClose)
  418.                 doCloseWindow();
  419.             else if(menuItem == iQuit)
  420.             {
  421.                 CallInScrapPromises();
  422.                 gDone = true;
  423.             }
  424.             break;
  425.  
  426.         case mEdit:
  427.             switch(menuItem)
  428.             {
  429.                 case iCut:
  430.                     doCutCopyCommand(true);
  431.                     break;
  432.  
  433.                 case iCopy:
  434.                     doCutCopyCommand(false);
  435.                     break;
  436.  
  437.                 case iPaste:
  438.                     doPasteCommand();
  439.                     break;
  440.  
  441.                 case iClear:
  442.                     doClearCommand();
  443.                     break;
  444.  
  445.                 case iClipboard:
  446.                     doClipboardCommand();
  447.                     break;
  448.             }
  449.             break;        
  450.     }
  451.  
  452.     HiliteMenu(0);
  453. }
  454.  
  455. // ****************************************************************************** doErrorAlert
  456.  
  457. void  doErrorAlert(SInt16 errorCode)
  458. {
  459.     Str255    errorString;
  460.     SInt16    itemHit;
  461.  
  462.     GetIndString(errorString,rErrorStrings,errorCode);
  463.     StandardAlert(kAlertStopAlert,errorString,NULL,NULL,&itemHit);
  464.     ExitToShell();
  465. }
  466.  
  467. // ***************************************************************************** doOpenWindows
  468.  
  469. void  doOpenWindows(void)
  470. {
  471.     SInt16                            a;
  472.     WindowRef                        windowRef;
  473.     docStructureHandle    docStrucHdl;
  474.     Rect                                theRect;
  475.  
  476.     for(a=0;a<2;a++)
  477.     {
  478.         if(!(windowRef = GetNewCWindow(rWindow + a,NULL,(WindowRef) -1)))
  479.             doErrorAlert(eFailWindow);
  480.         gWindowRefs[a] = windowRef;
  481.  
  482.         if(!(docStrucHdl = (docStructureHandle) NewHandle(sizeof(docStructure))))
  483.             doErrorAlert(eFailDocStruc);
  484.         SetWRefCon(windowRef,(SInt32) docStrucHdl);
  485.  
  486.         (*docStrucHdl)->pictureHdl = NULL;
  487.         (*docStrucHdl)->textHdl         = NULL;
  488.         (*docStrucHdl)->windowType = kDocumentType;
  489.         (*docStrucHdl)->selectFlag = false;
  490.     
  491.         SetPortWindowPort(windowRef);
  492.         TextSize(10);
  493.  
  494.         if(gRunningOnX)
  495.         {
  496.             GetWindowPortBounds(windowRef,&theRect);
  497.             InsetRect(&theRect,40,40);
  498.             ClipRect(&theRect);
  499.         }
  500.  
  501.         if(a == 0)
  502.             (*docStrucHdl)->textHdl = (Handle) GetResource('TEXT',rText);
  503.         else
  504.             (*docStrucHdl)->pictureHdl = GetPicture(rPicture);
  505.     }
  506. }
  507.  
  508. // ***************************************************************************** doCloseWindow
  509.  
  510. void  doCloseWindow(void)
  511. {
  512.     WindowRef                        windowRef;
  513.     docStructureHandle    docStrucHdl;
  514.     MenuRef                            editMenuRef;
  515.  
  516.     windowRef = FrontWindow();
  517.     docStrucHdl = (docStructureHandle) GetWRefCon(windowRef);
  518.  
  519.     if((*docStrucHdl)->windowType == kClipboardType)
  520.     {
  521.         DisposeWindow(windowRef);
  522.         gClipboardWindowRef = NULL;
  523.         gClipboardShowing = false;
  524.         editMenuRef = GetMenuRef(mEdit);
  525.         SetMenuItemText(editMenuRef,iClipboard,"\pShow Clipboard");
  526.     }
  527. }
  528.  
  529. // ******************************************************************************* doInContent
  530.  
  531. void  doInContent(Point mouseXY)
  532. {
  533.     WindowRef                        windowRef;
  534.     docStructureHandle    docStrucHdl;
  535.     GrafPtr                            oldPort;
  536.     Rect                                theRect;
  537.  
  538.     windowRef = FrontWindow();
  539.     docStrucHdl = (docStructureHandle) GetWRefCon(windowRef);
  540.  
  541.     if((*docStrucHdl)->windowType == kClipboardType)
  542.         return;
  543.  
  544.     GetPort(&oldPort);
  545.     SetPortWindowPort(windowRef);
  546.  
  547.     if((*docStrucHdl)->textHdl != NULL || (*docStrucHdl)->pictureHdl != NULL)
  548.     {
  549.         if((*docStrucHdl)->textHdl != NULL)
  550.         {
  551.             GetWindowPortBounds(windowRef,&theRect);
  552.             InsetRect(&theRect,40,40);
  553.         }
  554.         else if((*docStrucHdl)->pictureHdl != NULL) 
  555.         {
  556.             theRect = doSetDestRect(&(*(*docStrucHdl)->pictureHdl)->picFrame,windowRef);
  557.         }
  558.  
  559.         GlobalToLocal(&mouseXY);
  560.  
  561.         if(PtInRect(mouseXY,&theRect) && (*docStrucHdl)->selectFlag == false)
  562.         {
  563.             (*docStrucHdl)->selectFlag = true;
  564.             InvertRect(&theRect);
  565.         }
  566.         else if(!PtInRect(mouseXY,&theRect) && (*docStrucHdl)->selectFlag == true)
  567.         {
  568.             (*docStrucHdl)->selectFlag = false;
  569.             InvertRect(&theRect);
  570.         }
  571.     }
  572.  
  573.     SetPort(oldPort);
  574. }
  575.  
  576. // ************************************************************************** doCutCopyCommand
  577.  
  578. void  doCutCopyCommand(Boolean cutFlag)
  579. {
  580.     WindowRef                        windowRef;
  581.     docStructureHandle    docStrucHdl;    
  582.     OSStatus                        osError;
  583.     ScrapRef                        scrapRef;
  584.     Size                                dataSize;
  585.     GrafPtr                            oldPort;
  586.     Rect                                portRect;
  587.  
  588.     windowRef = FrontWindow();
  589.     docStrucHdl = (docStructureHandle) GetWRefCon(windowRef);
  590.  
  591.     if((*docStrucHdl)->selectFlag == false)
  592.         return;
  593.  
  594.     osError = ClearCurrentScrap();
  595.     if(osError == noErr)
  596.     {
  597.         GetCurrentScrap(&scrapRef);
  598.  
  599.         if((*docStrucHdl)->textHdl != NULL)  // ……………………………………………………………………………………………………………………'TEXT'
  600.         {
  601.             dataSize = GetHandleSize((Handle) (*docStrucHdl)->textHdl);
  602.             HLock((*docStrucHdl)->textHdl);
  603.  
  604.             osError = PutScrapFlavor(scrapRef,kScrapFlavorTypeText,kScrapFlavorMaskNone,
  605.                                                              dataSize,*((*docStrucHdl)->textHdl));
  606.             if(osError != noErr)
  607.                 doErrorAlert(ePutScrapFlavor);
  608.         }
  609.         else if((*docStrucHdl)->pictureHdl != NULL)  // …………………………………………………………………………………………… 'PICT'
  610.         {
  611.             dataSize = GetHandleSize((Handle) (*docStrucHdl)->pictureHdl);
  612.             HLock((Handle) (*docStrucHdl)->pictureHdl);
  613.  
  614.             osError = PutScrapFlavor(scrapRef,kScrapFlavorTypePicture,kScrapFlavorMaskNone,
  615.                                                               dataSize,*((Handle) (*docStrucHdl)->pictureHdl));
  616.             if(osError != noErr)
  617.                 doErrorAlert(ePutScrapFlavor);
  618.         }
  619.  
  620.         if((*docStrucHdl)->textHdl != NULL)
  621.             HUnlock((*docStrucHdl)->textHdl);
  622.         if((*docStrucHdl)->pictureHdl != NULL)
  623.             HUnlock((Handle) (*docStrucHdl)->pictureHdl);
  624.     }
  625.     else
  626.         doErrorAlert(eClearScrap);
  627.  
  628.     if(cutFlag)
  629.     {
  630.         GetPort(&oldPort);
  631.         SetPortWindowPort(windowRef);
  632.  
  633.         if((*docStrucHdl)->pictureHdl != NULL)
  634.         {
  635.             DisposeHandle((Handle) (*docStrucHdl)->pictureHdl);
  636.             (*docStrucHdl)->pictureHdl = NULL;
  637.             (*docStrucHdl)->selectFlag = false;
  638.         }
  639.         if((*docStrucHdl)->textHdl != NULL)
  640.         {
  641.             DisposeHandle((*docStrucHdl)->textHdl);
  642.             (*docStrucHdl)->textHdl = NULL;
  643.             (*docStrucHdl)->selectFlag = false;
  644.         }
  645.  
  646.         GetWindowPortBounds(windowRef,&portRect);
  647.         EraseRect(&portRect);
  648.  
  649.         SetPort(oldPort);
  650.     }
  651.  
  652.     if(gClipboardWindowRef != NULL)
  653.         doDrawClipboardWindow();
  654. }
  655.  
  656. // **************************************************************************** doPasteCommand
  657.  
  658. void  doPasteCommand(void)
  659. {
  660.     WindowRef                        windowRef;
  661.     docStructureHandle    docStrucHdl;    
  662.     GrafPtr                            oldPort;
  663.     ScrapRef                        scrapRef;
  664.     OSStatus                        osError;
  665.     ScrapFlavorFlags        flavorFlags;
  666.     Size                                sizeOfPictData = 0, sizeOfTextData = 0;
  667.     Handle                            newTextHdl, newPictHdl;
  668.     CFStringRef                    stringRef;
  669.     Rect                                destRect, portRect;    
  670.  
  671.     windowRef = FrontWindow();
  672.     docStrucHdl = (docStructureHandle) GetWRefCon(windowRef);
  673.  
  674.     GetPort(&oldPort);
  675.     SetPortWindowPort(windowRef);    
  676.  
  677.     GetCurrentScrap(&scrapRef);
  678.  
  679.     // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… 'TEXT'
  680.  
  681.     osError = GetScrapFlavorFlags(scrapRef,kScrapFlavorTypeText,&flavorFlags);
  682.     if(osError == noErr)
  683.     {
  684.         osError = GetScrapFlavorSize(scrapRef,kScrapFlavorTypeText,&sizeOfTextData);
  685.         if(osError == noErr && sizeOfTextData > 0)
  686.         {
  687.             newTextHdl = NewHandle(sizeOfTextData);    
  688.             osError = MemError();
  689.             if(osError == memFullErr)
  690.                 doErrorAlert(eFailMemory);
  691.  
  692.             HLock(newTextHdl);
  693.  
  694.             osError = GetScrapFlavorData(scrapRef,kScrapFlavorTypeText,&sizeOfTextData,*newTextHdl);
  695.             if(osError != noErr)
  696.                 doErrorAlert(eGetScrapData);
  697.  
  698.             // …………………………………………………………………………………………………………………………………………………………………………… draw text in window
  699.  
  700.             GetWindowPortBounds(windowRef,&portRect);
  701.             EraseRect(&portRect);
  702.             InsetRect(&portRect,40,40);
  703.             
  704.             if(!gRunningOnX)
  705.             {
  706.                 TETextBox(*newTextHdl,sizeOfTextData,&portRect,teFlushLeft);
  707.             }
  708.             else
  709.             {
  710.                 stringRef =    CFStringCreateWithBytes(NULL,(UInt8 *) *newTextHdl,sizeOfTextData,
  711.                                                                                         smSystemScript,false);
  712.                 DrawThemeTextBox(stringRef,kThemeSmallSystemFont,kThemeStateActive,true,&portRect,
  713.                                                  teFlushLeft,NULL);
  714.                 if(stringRef != NULL)
  715.                     CFRelease(stringRef);
  716.             }
  717.  
  718.             HUnlock(newTextHdl);
  719.  
  720.             (*docStrucHdl)->selectFlag = false;
  721.  
  722.             // ………………………………………………………………………… assign handle to new text to window's document structure
  723.  
  724.             if((*docStrucHdl)->textHdl != NULL)
  725.                 DisposeHandle((*docStrucHdl)->textHdl);
  726.             (*docStrucHdl)->textHdl = newTextHdl;
  727.  
  728.             if((*docStrucHdl)->pictureHdl != NULL)
  729.                 DisposeHandle((Handle) (*docStrucHdl)->pictureHdl);
  730.             (*docStrucHdl)->pictureHdl = NULL;
  731.         }
  732.         else
  733.             doErrorAlert(eGetScrapSize);
  734.     }
  735.  
  736.     // ……………………………………………………………………………………………………………………………………………………………………………………………………………………… ' PICT'
  737.  
  738.     else 
  739.     {
  740.         (osError = GetScrapFlavorFlags(scrapRef,kScrapFlavorTypePicture,&flavorFlags));
  741.         if(osError == noErr)
  742.         {
  743.             osError = GetScrapFlavorSize(scrapRef,kScrapFlavorTypePicture,&sizeOfPictData);
  744.             if(osError == noErr && sizeOfPictData > 0)
  745.             {
  746.                 newPictHdl = NewHandle(sizeOfPictData);    
  747.                 osError = MemError();
  748.                 if(osError == memFullErr)
  749.                     doErrorAlert(eFailMemory);
  750.  
  751.                 HLock(newPictHdl);
  752.  
  753.                 osError = GetScrapFlavorData(scrapRef,kScrapFlavorTypePicture,&sizeOfPictData,
  754.                                                                      *newPictHdl);
  755.                 if(osError != noErr)
  756.                     doErrorAlert(eGetScrapData);
  757.  
  758.                 // ……………………………………………………………………………………………………………………………………………………………… draw picture in window
  759.  
  760.                 GetWindowPortBounds(windowRef,&portRect);
  761.                 EraseRect(&portRect);
  762.                 (*docStrucHdl)->selectFlag = false;
  763.                 destRect = doSetDestRect(&(*(PicHandle) newPictHdl)->picFrame,windowRef);
  764.                 DrawPicture((PicHandle) newPictHdl,&destRect);
  765.  
  766.                 HUnlock(newPictHdl);
  767.  
  768.                 (*docStrucHdl)->selectFlag = false;
  769.  
  770.                 // …………………………………………………………… assign handle to new picture to window's document structure
  771.  
  772.                 if((*docStrucHdl)->pictureHdl != NULL)
  773.                     DisposeHandle((Handle) (*docStrucHdl)->pictureHdl);
  774.                 (*docStrucHdl)->pictureHdl = (PicHandle) newPictHdl;
  775.  
  776.                 if((*docStrucHdl)->textHdl != NULL)
  777.                     DisposeHandle((Handle) (*docStrucHdl)->textHdl);
  778.                 (*docStrucHdl)->textHdl = NULL;
  779.             }
  780.             else
  781.                 doErrorAlert(eGetScrapSize);
  782.         }
  783.     }
  784.  
  785.     SetPort(oldPort);
  786. }
  787.  
  788. // **************************************************************************** doClearCommand
  789.  
  790. void  doClearCommand(void)
  791. {
  792.     WindowRef                        windowRef;
  793.     docStructureHandle    docStrucHdl;    
  794.     GrafPtr                            oldPort;
  795.     Rect                                portRect;
  796.  
  797.     windowRef = FrontWindow();
  798.     docStrucHdl = (docStructureHandle) GetWRefCon(windowRef);
  799.  
  800.     GetPort(&oldPort);
  801.     SetPortWindowPort(windowRef);
  802.  
  803.     if((*docStrucHdl)->textHdl != NULL)
  804.     {
  805.         DisposeHandle((*docStrucHdl)->textHdl);
  806.         (*docStrucHdl)->textHdl = NULL;
  807.     }
  808.  
  809.     if((*docStrucHdl)->pictureHdl != NULL)
  810.     {
  811.         DisposeHandle((Handle) (*docStrucHdl)->pictureHdl);
  812.         (*docStrucHdl)->pictureHdl = NULL;
  813.     }
  814.     
  815.     (*docStrucHdl)->selectFlag = false;
  816.  
  817.     GetWindowPortBounds(windowRef,&portRect);
  818.     EraseRect(&portRect);
  819.  
  820.     SetPort(oldPort);
  821. }
  822.  
  823. // ************************************************************************ doClipboardCommand
  824.  
  825. void  doClipboardCommand(void)
  826. {
  827.     MenuRef                            editMenuRef;
  828.     docStructureHandle    docStrucHdl;    
  829.  
  830.     editMenuRef = GetMenuRef(mEdit);
  831.  
  832.     if(gClipboardWindowRef == NULL)
  833.     {
  834.         if(!(gClipboardWindowRef = GetNewCWindow(rClipboardWindow,NULL,(WindowRef)-1)))
  835.             doErrorAlert(eFailWindow);
  836.         if(!(docStrucHdl = (docStructureHandle) NewHandle(sizeof(docStructure))))
  837.             doErrorAlert(eFailDocStruc);
  838.  
  839.         SetWRefCon(gClipboardWindowRef,(SInt32) docStrucHdl);
  840.         (*docStrucHdl)->windowType = kClipboardType;
  841.  
  842.         SetMenuItemText(editMenuRef,iClipboard,"\pHide Clipboard");
  843.             
  844.         gClipboardShowing = true;
  845.     }
  846.     else
  847.     {
  848.         if(gClipboardShowing)
  849.         {
  850.             HideWindow(gClipboardWindowRef);
  851.             gClipboardShowing = false;
  852.             SetMenuItemText(editMenuRef,iClipboard,"\pShow Clipboard");
  853.         }
  854.         else
  855.         {
  856.             ShowWindow(gClipboardWindowRef);
  857.             gClipboardShowing = true;
  858.             SetMenuItemText(editMenuRef,iClipboard,"\pHide Clipboard");                
  859.         }
  860.     }
  861. }
  862.  
  863. // ********************************************************************* doDrawClipboardWindow
  864.  
  865. void  doDrawClipboardWindow(void)
  866. {
  867.     GrafPtr                        oldPort;
  868.     Rect                            theRect, textBoxRect;
  869.     ScrapRef                    scrapRef;
  870.     OSStatus                    osError;
  871.     ScrapFlavorFlags    flavorFlags;
  872.     CFStringRef                stringRef;
  873.     Handle                        tempHdl;
  874.     Size                            sizeOfPictData = 0, sizeOfTextData = 0;
  875.     RGBColor                    blackColour = { 0x0000, 0x0000, 0x0000 };
  876.     
  877.     GetPort(&oldPort);
  878.     SetPortWindowPort(gClipboardWindowRef);    
  879.  
  880.     GetWindowPortBounds(gClipboardWindowRef,&theRect);
  881.     EraseRect(&theRect);
  882.  
  883.     SetRect(&theRect,-1,-1,597,24);
  884.     DrawThemeWindowHeader(&theRect,gClipboardWindowRef == FrontWindow());
  885.  
  886.     if(gClipboardWindowRef == FrontWindow())
  887.         TextMode(srcOr);
  888.     else
  889.       TextMode(grayishTextOr);
  890.  
  891.     SetRect(&textBoxRect,10,5,120,20);
  892.     DrawThemeTextBox(CFSTR("Clipboard Contents:"),kThemeSmallSystemFont,0,true,&textBoxRect,
  893.                                      teJustLeft,NULL);
  894.  
  895.     GetCurrentScrap(&scrapRef);
  896.  
  897.     // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… 'TEXT'
  898.  
  899.     osError = GetScrapFlavorFlags(scrapRef,kScrapFlavorTypeText,&flavorFlags);
  900.     if(osError == noErr)
  901.     {
  902.         osError = GetScrapFlavorSize(scrapRef,kScrapFlavorTypeText,&sizeOfTextData);
  903.         if(osError == noErr && sizeOfTextData > 0)
  904.         {
  905.             SetRect(&textBoxRect,120,5,597,20);
  906.             DrawThemeTextBox(CFSTR("Text"),kThemeSmallSystemFont,0,true,&textBoxRect,teJustLeft,
  907.                                              NULL);
  908.  
  909.             tempHdl = NewHandle(sizeOfTextData);    
  910.             osError = MemError();
  911.             if(osError == memFullErr)
  912.                 doErrorAlert(eFailMemory);
  913.  
  914.             HLock(tempHdl);
  915.  
  916.             osError = GetScrapFlavorData(scrapRef,kScrapFlavorTypeText,&sizeOfTextData,*tempHdl);
  917.             if(osError != noErr)
  918.                 doErrorAlert(eGetScrapData);
  919.  
  920.             // ………………………………………………………………………………………………………………………………………………… draw text in clipboard window
  921.  
  922.             GetWindowPortBounds(gClipboardWindowRef,&theRect);
  923.             theRect.top += 24;
  924.             InsetRect(&theRect,2,2);
  925.  
  926.             if(sizeOfTextData >= 965)
  927.                 sizeOfTextData = 965;
  928.             stringRef =    CFStringCreateWithBytes(NULL,(UInt8 *) *tempHdl,sizeOfTextData,
  929.                                                                                     CFStringGetSystemEncoding(),true);        
  930.             DrawThemeTextBox(stringRef,kThemeSmallSystemFont,0,true,&theRect,teFlushLeft,NULL);
  931.             if(stringRef != NULL)
  932.                 CFRelease(stringRef);
  933.  
  934.             HUnlock(tempHdl);
  935.             DisposeHandle(tempHdl);
  936.         }
  937.         else
  938.             doErrorAlert(eGetScrapSize);
  939.     }
  940.  
  941.     // ………………………………………………………………………………………………………………………………………………………………………………………………………………………… 'PICT'
  942.  
  943.     else 
  944.     {
  945.         osError = GetScrapFlavorFlags(scrapRef,kScrapFlavorTypePicture,&flavorFlags);
  946.         if(osError == noErr)
  947.         {
  948.             osError = GetScrapFlavorSize(scrapRef,kScrapFlavorTypePicture,&sizeOfPictData);
  949.             if(osError == noErr && sizeOfPictData > 0)
  950.             {
  951.                 SetRect(&textBoxRect,120,5,597,20);
  952.                 DrawThemeTextBox(CFSTR("Picture"),kThemeSmallSystemFont,0,true,&textBoxRect,
  953.                                                  teJustLeft,NULL);
  954.  
  955.                 tempHdl = NewHandle(sizeOfPictData);
  956.                 osError = MemError();
  957.                 if(osError == memFullErr)
  958.                     doErrorAlert(eFailMemory);
  959.  
  960.                 HLock(tempHdl);
  961.  
  962.                 osError = GetScrapFlavorData(scrapRef,kScrapFlavorTypePicture,&sizeOfPictData,
  963.                                                                          *tempHdl);
  964.                 if(osError != noErr)
  965.                     doErrorAlert(eGetScrapData);
  966.  
  967.                 // …………………………………………………………………………………………………………………………………… draw picture in clipboard window
  968.  
  969.                 theRect = (*(PicHandle) tempHdl)->picFrame;
  970.                 OffsetRect(&theRect,-((*(PicHandle) tempHdl)->picFrame.left - 2),
  971.                                                       -((*(PicHandle) tempHdl)->picFrame.top - 26));
  972.                 DrawPicture((PicHandle) tempHdl,&theRect);
  973.  
  974.                 HUnlock(tempHdl);
  975.                 DisposeHandle(tempHdl);
  976.             }
  977.             else
  978.                 doErrorAlert(eGetScrapSize);
  979.         }
  980.     }
  981.  
  982.     TextMode(srcOr);
  983.     SetPort(oldPort);
  984. }
  985.  
  986. // ********************************************************************** doDrawDocumentWindow
  987.  
  988. void  doDrawDocumentWindow(WindowRef windowRef)
  989. {
  990.     GrafPtr                            oldPort;
  991.     docStructureHandle    docStrucHdl;
  992.     Rect                              destRect;
  993.     CFStringRef                    stringRef;
  994.  
  995.     GetPort(&oldPort);
  996.     SetPortWindowPort(windowRef);
  997.  
  998.     docStrucHdl = (docStructureHandle) GetWRefCon(windowRef);
  999.  
  1000.     if((*docStrucHdl)->textHdl != NULL)
  1001.     {
  1002.         GetWindowPortBounds(windowRef,&destRect);
  1003.         InsetRect(&destRect,40,40);
  1004.  
  1005.         stringRef =    CFStringCreateWithBytes(NULL,(UInt8 *) *(*docStrucHdl)->textHdl,
  1006.                                                                                 GetHandleSize((*docStrucHdl)->textHdl),
  1007.                                                                                 smSystemScript,false);
  1008.         DrawThemeTextBox(stringRef,kThemeSmallSystemFont,0,true,&destRect,teFlushLeft,NULL);
  1009.         if(stringRef != NULL)
  1010.             CFRelease(stringRef);
  1011.  
  1012.         if((*docStrucHdl)->selectFlag)
  1013.             InvertRect(&destRect);
  1014.     }
  1015.     else if((*docStrucHdl)->pictureHdl != NULL)
  1016.     {
  1017.         destRect = doSetDestRect(&(*(*docStrucHdl)->pictureHdl)->picFrame,windowRef);
  1018.         DrawPicture((*docStrucHdl)->pictureHdl,&destRect);
  1019.         if((*docStrucHdl)->selectFlag)
  1020.             InvertRect(&destRect);
  1021.     }
  1022.  
  1023.     SetPort(oldPort);
  1024. }
  1025.  
  1026. // ***************************************************************************** doSetDestRect
  1027.  
  1028. Rect  doSetDestRect(Rect *picFrame,WindowRef windowRef)
  1029. {
  1030.     Rect        destRect, portRect;
  1031.     SInt16    diffX, diffY;
  1032.  
  1033.     destRect = *picFrame;
  1034.     GetWindowPortBounds(windowRef,&portRect);
  1035.     
  1036.     OffsetRect(&destRect,-(*picFrame).left,-(*picFrame).top);
  1037.  
  1038.     diffX = (portRect.right - portRect.left) - ((*picFrame).right - (*picFrame).left);
  1039.     diffY = (portRect.bottom - portRect.top) - ((*picFrame).bottom - (*picFrame).top);
  1040.  
  1041.     OffsetRect(&destRect,diffX / 2,diffY / 2);
  1042.     
  1043.     return destRect;
  1044. }
  1045.  
  1046. // *********************************************************************** doGetDepthAndDevice
  1047.  
  1048. void doGetDepthAndDevice(void)
  1049. {
  1050.     GDHandle    deviceHdl;
  1051.  
  1052.     deviceHdl = GetMainDevice();
  1053.     gPixelDepth = (*(*deviceHdl)->gdPMap)->pixelSize;
  1054.     if(((1 << gdDevType) & (*deviceHdl)->gdFlags) != 0)
  1055.         gIsColourDevice = true;
  1056. }
  1057.  
  1058. // *******************************************************************************************
  1059.